package org.ala.distributed_redis_transaction.commons;

import java.util.function.Consumer;

import org.ala.distributed_transaction_commons.AbstractDistributedTransaction;
import org.ala.distributed_transaction_commons.DistributedTransactionStatus;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;


/**
 * redis分布式事务
 * 
 * @author 骆毅(ala)
 * @date 2024年2月28日
 */
public class AbstractRedisTransaction extends AbstractDistributedTransaction {

	
	/**
	 * redis连接池
	 */
	protected JedisPool pool;
	/**
	 * redis链接
	 */
	protected Jedis conn;
	/**
	 * 事务
	 */
	protected Transaction tx;
	
	
	/**
	 * 准备提交阶段，拿redis链接，开启事务
	 */
	@Override
	protected void doCanCommit() {
		Jedis jedis = pool.getResource();
		tx = jedis.multi();
	}
	/**
	 * 预提交阶段的操作
	 */
	public void doPreCommit(Consumer<Transaction> consumer) {
		consumer.accept(tx);
	}
	
	
	/**
	 * 默认pre_commit和commit合并到commit一个方法中
	 * <p>	但实际执行流程还是一步一步来，只是两个方法合并成一个
	 */
	public void commit() {
		//	如果当前处于can_commit状态，执行预提交
		if (DistributedTransactionStatus.CAN_COMMIT.equals(this.status())) {
			super.preCommit();
		}
		//	执行提交
		super.commit();
	}
	/**
	 * 真实提交数据
	 */
	@Override
	protected void doCommit() {
		tx.exec();
	}
	/**
	 * 完成后的回调
	 */
	@Override
	protected void doOnFinished() {
		pool.returnResource(conn);
	}
	
	
	/**
	 * can提交阶段的回滚
	 */
	@Override
	protected void doRollbackWithCanCommit() {
		pool.returnResource(conn);
	}
	/**
	 * 与提交阶段的回滚
	 */
	@Override
	protected void doRollbackWithPreCommit() {
		tx.discard();
		pool.returnResource(conn);
	}
	/**
	 * commit阶段发生了rollback
	 * <p>	执行补偿操作
	 */
	@Override
	protected void doRollbackWithCommited() {
		try {
			if (compensation != null) {
				compensation.compensation();
			}
		} finally {
			pool.returnResource(conn);
		}
	}
	
	
	public JedisPool getPool() {
		return pool;
	}
	public void setPool(JedisPool pool) {
		this.pool = pool;
	}
}
